moduleAplicacao.directive('uiTree', function() {
    return {
        template: '<ul class="uiTree"><ui-tree-node ng-repeat="node in tree"></ui-tree-node></ul>',
        replace: true,
        transclude: true,
        restrict: 'E',
        scope: {
            tree: '=ngModel',
            attrNodeId: "@",
            loadFn: '=',
            expandTo: '=',
            selectedId: '='
        },
        controller: function($scope, $element, $attrs) {
            $scope.loadFnName = $attrs.loadFn;
            // this seems like an egregious hack, but it is
            // necessary for recursively-generated
            // trees to have access to the loader function
            if ($scope.$parent.loadFn)
                $scope.loadFn = $scope.$parent.loadFn;

            // TODO expandTo shouldn't be two-way, currently
            // we're copying it
            if ($scope.expandTo && $scope.expandTo.length) {
                $scope.expansionNodes = angular.copy($scope.expandTo);
                var arrExpandTo = $scope.expansionNodes.split(",");
                $scope.nextExpandTo = arrExpandTo.shift();
                $scope.expansionNodes = arrExpandTo.join(",");
            }
        }
    };
}).directive('uiTreeNode', ['$compile', '$timeout', function($compile, $timeout) {
        return {
            restrict: 'E',
            replace: true,
            template: '<li>' +
                    '<div title="{{getTooltip(node)}}" ng-show="!node.themes || (node.themes && node.themes.length < 2)" class="node" data-node-id="{{ nodeId() }}">' +
                    '<a class="arrow" ng-click="toggleNode(node)"></a>' +
                    '<a class="uiTree-checkbox" ng-click="toggleNodeCheck(node)"></a>' +
                    '<span class="icon"></span>' +
                    '<a ng-hide="selectedId" ng-href="#/assets/{{ nodeId() }}">{{ node.name }}</a>' +
                    '<span ng-show="selectedId" ng-class="css()" ng-click="setSelected(node)">{{ node.name }}</span>' +
                    '</div>' +
                    '<div title="{{getTooltip(node)}}" ng-show="node.themes && node.themes.length > 1" class="node" data-node-id="{{ nodeId() }}">' +
                    '<a class="arrow" ng-click="toggleNode(node)"></a>' +
                    '<a class="uiTree-checkbox" ng-click="toggleNodeCheck(node)" ng-show="exibeTema(node)"></a>' +
                    '<a ng-hide="selectedId" ng-href="#/assets/{{ nodeId() }}">{{ node.name }}</a>' +
                    '<span ng-show="selectedId" ng-class="css()" ng-click="setSelected(node)">{{ node.name }}</span>' +
                    '<div class="node-themes" ng-repeat="theme in node.themes">' +
                    '<div class="tema" id="{{ nodeId() }}" ng-show="theme && node.checked" >' +
                    //'<span class="icon" style="{{theme.style}}"></span>' +
                    '<span ng-show="selectedId" ng-class="css()" style="padding-left:20px" ng-click="setSelected(node)">{{ theme.legend }}</span>' +
                    '</div>' +
                    '</div>' +
                    '</div>' +
                    '</li>',
            link: function(scope, elm, attrs) {
                scope.nodeId = function(node) {
                    var localNode = node || scope.node;
                    return localNode[scope.attrNodeId];
                };

                scope.getTooltip = function(node) {
                    if (node != undefined && node != null && node.layer != undefined && node.layer != null && node.layer.scaleRanges != undefined && node.layer.scaleRanges != null) {
                        var scaleRange = node.layer.scaleRanges[0];
                        return node.layer.name + " - Visível de " + scaleRange.minScale.toFixed(0) + " a " + scaleRange.maxScale.toFixed(0);
                    }
                    return "";
                };

                scope.toggleNode = function(node) {
                    var isVisible = elm.children(".uiTree:visible").length > 0;
                    var childrenTree = elm.children(".uiTree");

                    if (isVisible) {
                        scope.$emit('nodeCollapsed', node);
                    } else if (node) {
                        scope.$emit('nodeExpanded', node);
                    }

                    if (!isVisible && scope.loadFn && childrenTree.length === 0) {
                        // load the children asynchronously
                        var callback = function(arrChildren) {
                            scope.node.children = arrChildren;
                            scope.appendChildren();
                            elm.find("a.arrow i").show();
                            elm.find("a.arrow img").remove();
                            scope.toggleNode(); // show it
                        };

                        var promiseOrNodes = scope.loadFn(node, callback);

                        if (promiseOrNodes && promiseOrNodes.then) {
                            promiseOrNodes.then(callback);
                        } else {
                            $timeout(function() {
                                callback(promiseOrNodes);
                            }, 0);
                        }

                        elm.find("a.arrow i").hide();
                        var imgUrl = "resources/images/ajax-loader.gif";
                        elm.find("a.arrow").append('<img src="' + imgUrl + '" width="16" height="16">');
                    } else {
                        childrenTree.toggle(!isVisible);
                        elm.find("a.arrow i").toggleClass("icon-arrow-right");
                        elm.find("a.arrow i").toggleClass("icon-arrow-down");
                    }
                };

                scope.exibeTema = function(nodeName) {
                    var subTema = elm.find("div.tema");
                    for (var j = 0; j < subTema.length; j++) {
                        if(nodeName.assetId == subTema[j].id){
                            for (var i = 0; i < nodeName.themes.length; i++) {
                                if($(subTema[j]).text() == nodeName.themes[i].legend){
                                    //subTema[j].style = "display:block; background: no-repeat; background-position:15% 65%; background-image: url(" + nodeName.themes[i].icon + "); padding-left:33px";
                                    if(subTema[j].style.display == ""){
                                        subTema[j].style.display = "block";
                                        subTema[j].style.background = "no-repeat";
                                        subTema[j].style.backgroundPosition = "15% 65%";
                                        subTema[j].style.paddingLeft = "33px";
                                        subTema[j].style.backgroundImage = 'url("'+ nodeName.themes[i].icon+'")';
                                    }
                                }
                            }
                        }
                    }
                    return true;
                };

                scope.toggleNodeCheck = function(node) {
                    x = node;
                    if (!node.checked) {
                        node.checked = true;
                    }
                    else {
                        node.checked = false;
                    }
                    
                    var el = elm.find("a.uiTree-checkbox");
                    var checked = el.hasClass("checked");
                    var radio = el.hasClass("radio-item");

                    if (radio) {
                        if (!checked) {
                            el.toggleClass("checked");
                            scope.$emit("nodeCheckChange", node, checked);
                        }
                    } else {
                        el.toggleClass("checked");
                        checked = el.hasClass("checked");
                        scope.$emit("nodeCheckChange", node, checked);

                        divThemes = elm.find("div.node-themes");
                        if (checked) {
                            divThemes.css("display", "block");
                        }
                        else {
                            divThemes.css("display", "none");
                        }
                    }

                };

                scope.appendChildren = function() {
                    // Add children by $compiling and doing
                    // a new ui-tree directive
                    // We need the load-fn attribute in
                    // there if it has been provided
                    var childrenHtml = '<ui-tree ng-model="node.children" attr-node-id="' + scope.attrNodeId + '"';
                    if (scope.loadFn) {
                        childrenHtml += ' load-fn="' + scope.loadFnName + '"';
                    }

                    // pass along all the variables
                    if (scope.expansionNodes) {
                        childrenHtml += ' expand-to="expansionNodes"';
                    }

                    if (scope.selectedId) {
                        childrenHtml += ' selected-id="selectedId"';
                    }

                    childrenHtml += ' style="display: none"></ui-tree>';

                    return elm.append($compile(childrenHtml)(scope));
                };

                scope.css = function() {
                    return {
                        nodeLabel: true,
                        selected: scope.selectedId && scope.nodeId() === scope.selectedId
                    };

                };

                // emit an event up the scope. Then, from
                // the scope above this tree, a "selectNode"
                // event is expected to be broadcasted
                // downwards to each node in the tree.
                // TODO this needs to be re-thought such
                // that the controller doesn't need to
                // manually
                // broadcast "selectNode" from outside of
                // the directive scope.
                scope.setSelected = function(node) {
                    scope.$emit("nodeSelected", node);
                };

                scope.$on("selectNode", function(event, node) {
                    scope.selectedId = scope.nodeId(node);
                });

                if (scope.node.hasChildren) {
                    elm.find("a.arrow").append('<i class="icon-arrow-right"></i>');
                }
                
                elm.find("span.icon").hide();
                if (scope.node.icon != undefined) {
                    elm.find("span.icon").css("background-image", "url(" + scope.node.icon + ")");
                    elm.find("span.icon").show();
                }
                if (scope.node.style != undefined) {
                    elm.find("span.icon").attr('style', scope.node.style);
                    elm.find("span.icon").show();
                }

                elm.find("a.uiTree-checkbox").hide();
                if (scope.node.checked != undefined) {
                    if (scope.node.radioGroup != undefined) {
                        elm.find("a.uiTree-checkbox").addClass("radio-item");
                    }

                    if (scope.node.checked) {
                        elm.find("a.uiTree-checkbox").addClass("checked");
                    } else {
                        elm.find("a.uiTree-checkbox").addClass("unchecked");
                    }
                    elm.find("a.uiTree-checkbox").show();
                }

                if (scope.node.labelCls != undefined) {
                    elm.find("span[ng-show='selectedId']").addClass(scope.node.labelCls);
                }

                if (scope.nextExpandTo && scope.nodeId() == parseInt(scope.nextExpandTo, 10)) {
                    scope.toggleNode(scope.nodeId());
                }

                if (scope.node.expanded) {
                    scope.toggleNode(scope.node);
                }
            }
        };
    }]);